-module(code_lock).
-behaviour(gen_fsm).

-export([start_link/1]).
-export([button/1, locked/2, open/2]).
-export([init/1, handle_event/3, handle_sync_event/4, handle_info/3, code_change/4, terminate/3]).

start_link(Code) ->
    gen_fsm:start_link({local, code_lock}, code_lock, Code, []).

button(Digit) ->
    gen_fsm:send_event(code_lock, {button, Digit}).

init(Code) ->
    {ok, locked, {[], Code}}.

handle_event(_A, _B, _C) ->
    {next_state, ok, ok}.

handle_sync_event(_A, _B, _C, _D) ->
    {reply, ok, ok, ok}.

handle_info(_A, _B, _C) ->
    {next_state, ok, ok}.

code_change(_A, _B, _C, _D) ->
    {ok, ok, ok}.

terminate(_A, _B, _C) ->
    ok.

locked({button, Digit}, {SoFar, Code}) ->
    io:format("Now the code you input is: ~w~n", [SoFar ++ [Digit]]),
    case SoFar ++ [Digit] of
        Code ->
            io:format("Open!~n"),
            {next_state, open, {[], Code}, 3000};
        Incomplete when length(Incomplete) < length(Code) ->
            {next_state, locked, {Incomplete, Code}};
        _Wrong ->
            io:format("Wrong Code! Start Again!~n"),
            {next_state, locked, {[], Code}}
    end.

open(timeout, State) ->
    io:format("Lock!~n"),
    {next_state, locked, State}.
